<?php

namespace pUtils;

use ErrorException;
use PDO;
use Throwable;

class db {
    
    /**
     * @throws Throwable
     */
    public function conn($db = null): PDO|null {
        try {
            /**长连接 */
            // $conn = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
            
            if (utils::isNull(...list($type, $host, $port, $dbname, $username, $password) =
                utils::getVals(config::get($db ?? config::get("global", "defaultDB")), "type", "host", "port", "dbname", "username", "password"))) {
                
                utils::showErrMsg(new ErrorException("[db:$db] 配置加载失败"));
                
                return null;
            }
            
            $conn = match ($type) {
                "mssql" => new PDO("sqlsrv:Server=$host,$port;Database=$dbname", $username, $password),
                "oracle" => new PDO("oci:dbname=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = $host)(PORT = $port) ) ) (CONNECT_DATA = (SERVICE_NAME = $dbname) ) );charset=utf8",
                                    $username, $password),
                "mysql" => new PDO("mysql:host=$host;dbname=$dbname", $username, $password)
            };
            
            $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $conn->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
            $conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
            
            // $conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //sqlserver 报错
            
            return $conn;
        } catch (Throwable $e) {
            $this->showErrMsg($e);
            
            return null;
        }
    }
    
    private function showErrMsg(Throwable $e) {
        if (+config::get("global", "debug")) {
            utils::showErrMsg($e);
        }
    }
}